/*
 * geometry_debug_helper.h
 *
 *  Created on: 19-jun-2009
 *      Author: HPK
 */

#ifndef GEOMETRY_DEBUG_HELPER_H_
#define GEOMETRY_DEBUG_HELPER_H_

#include <GL/gl.h>
#include "model/cube.h"
#include "model/frustum.h"

// Simplemente se encarga de dibujar un Cube,Frustum,Rectangle dado sus modelos
class GeometryDebugHelper{
	public:
		static void drawCube(const Cube& box,bool drawNormals=false){
			glBegin(GL_LINES);
				glVertex3f(box.vertices()[0].x1,box.vertices()[0].x2,box.vertices()[0].x3);
				glVertex3f(box.vertices()[1].x1,box.vertices()[1].x2,box.vertices()[1].x3);
				glVertex3f(box.vertices()[1].x1,box.vertices()[1].x2,box.vertices()[1].x3);
				glVertex3f(box.vertices()[2].x1,box.vertices()[2].x2,box.vertices()[2].x3);
				glVertex3f(box.vertices()[2].x1,box.vertices()[2].x2,box.vertices()[2].x3);
				glVertex3f(box.vertices()[3].x1,box.vertices()[3].x2,box.vertices()[3].x3);
				glVertex3f(box.vertices()[3].x1,box.vertices()[3].x2,box.vertices()[3].x3);
				glVertex3f(box.vertices()[0].x1,box.vertices()[0].x2,box.vertices()[0].x3);
				glVertex3f(box.vertices()[0].x1,box.vertices()[0].x2,box.vertices()[0].x3);
				glVertex3f(box.vertices()[4].x1,box.vertices()[4].x2,box.vertices()[4].x3);
				glVertex3f(box.vertices()[1].x1,box.vertices()[1].x2,box.vertices()[1].x3);
				glVertex3f(box.vertices()[5].x1,box.vertices()[5].x2,box.vertices()[5].x3);
				glVertex3f(box.vertices()[2].x1,box.vertices()[2].x2,box.vertices()[2].x3);
				glVertex3f(box.vertices()[6].x1,box.vertices()[6].x2,box.vertices()[6].x3);
				glVertex3f(box.vertices()[3].x1,box.vertices()[3].x2,box.vertices()[3].x3);
				glVertex3f(box.vertices()[7].x1,box.vertices()[7].x2,box.vertices()[7].x3);
				glVertex3f(box.vertices()[4].x1,box.vertices()[4].x2,box.vertices()[4].x3);
				glVertex3f(box.vertices()[5].x1,box.vertices()[5].x2,box.vertices()[5].x3);
				glVertex3f(box.vertices()[5].x1,box.vertices()[5].x2,box.vertices()[5].x3);
				glVertex3f(box.vertices()[6].x1,box.vertices()[6].x2,box.vertices()[6].x3);
				glVertex3f(box.vertices()[6].x1,box.vertices()[6].x2,box.vertices()[6].x3);
				glVertex3f(box.vertices()[7].x1,box.vertices()[7].x2,box.vertices()[7].x3);
				glVertex3f(box.vertices()[7].x1,box.vertices()[7].x2,box.vertices()[7].x3);
				glVertex3f(box.vertices()[4].x1,box.vertices()[4].x2,box.vertices()[4].x3);
			glEnd();

			if(drawNormals){
				//TODO
			}
		}

		static void drawFrusutm(const Frustum& f,bool drawNormals=false){
			glBegin(GL_LINES);
				glVertex3f(f.frontFace()[0].x1,f.frontFace()[0].x2,f.frontFace()[0].x3);
				glVertex3f(f.frontFace()[1].x1,f.frontFace()[1].x2,f.frontFace()[1].x3);

				glVertex3f(f.frontFace()[0].x1,f.frontFace()[0].x2,f.frontFace()[0].x3);
				glVertex3f(f.frontFace()[3].x1,f.frontFace()[3].x2,f.frontFace()[3].x3);

				glVertex3f(f.frontFace()[1].x1,f.frontFace()[1].x2,f.frontFace()[1].x3);
				glVertex3f(f.frontFace()[2].x1,f.frontFace()[2].x2,f.frontFace()[2].x3);

				glVertex3f(f.frontFace()[3].x1,f.frontFace()[3].x2,f.frontFace()[3].x3);
				glVertex3f(f.frontFace()[2].x1,f.frontFace()[2].x2,f.frontFace()[2].x3);


				glVertex3f(f.frontFace()[0].x1,f.frontFace()[0].x2,f.frontFace()[0].x3);
				glVertex3f(f.backFace()[0].x1,f.backFace()[0].x2,f.backFace()[0].x3);

				glVertex3f(f.frontFace()[1].x1,f.frontFace()[1].x2,f.frontFace()[1].x3);
				glVertex3f(f.backFace()[1].x1,f.backFace()[1].x2,f.backFace()[1].x3);

				glVertex3f(f.frontFace()[3].x1,f.frontFace()[3].x2,f.frontFace()[3].x3);
				glVertex3f(f.backFace()[3].x1,f.backFace()[3].x2,f.backFace()[3].x3);

				glVertex3f(f.frontFace()[2].x1,f.frontFace()[2].x2,f.frontFace()[2].x3);
				glVertex3f(f.backFace()[2].x1,f.backFace()[2].x2,f.backFace()[2].x3);


				glVertex3f(f.backFace()[0].x1,f.backFace()[0].x2,f.backFace()[0].x3);
				glVertex3f(f.backFace()[1].x1,f.backFace()[1].x2,f.backFace()[1].x3);

				glVertex3f(f.backFace()[0].x1,f.backFace()[0].x2,f.backFace()[0].x3);
				glVertex3f(f.backFace()[3].x1,f.backFace()[3].x2,f.backFace()[3].x3);

				glVertex3f(f.backFace()[1].x1,f.backFace()[1].x2,f.backFace()[1].x3);
				glVertex3f(f.backFace()[2].x1,f.backFace()[2].x2,f.backFace()[2].x3);

				glVertex3f(f.backFace()[2].x1,f.backFace()[2].x2,f.backFace()[2].x3);
				glVertex3f(f.backFace()[3].x1,f.backFace()[3].x2,f.backFace()[3].x3);
			glEnd();

			if(drawNormals){
				// normales del frustum
				// farPlane
				glColor3f(1.0f,0.0f,0.0f);
				glPushMatrix();
					Point p1 = ((f.backFace()[2]-f.backFace()[0])*(0.5f)) + f.backFace()[0];
					glTranslatef(p1.x1,p1.x2,p1.x3);
					glBegin(GL_LINES);
						glVertex3f(0,0,0);
						glVertex3f(f.normals()[0].x1,f.normals()[0].x2,f.normals()[0].x3);
					glEnd();
				glPopMatrix();

				// leftPlane
				glColor3f(0.0f,1.0f,0.0f);
				glPushMatrix();
					Point p2 = ((f.backFace()[1]-f.frontFace()[2])*(0.5f)) + f.frontFace()[2];
					glTranslatef(p2.x1,p2.x2,p2.x3);
					glBegin(GL_LINES);
						glVertex3f(0,0,0);
						glVertex3f(f.normals()[2].x1,f.normals()[2].x2,f.normals()[2].x3);
					glEnd();
				glPopMatrix();

				// topPlane
				glColor3f(0.0f,0.0f,1.0f);
				glPushMatrix();
					Point p3 = ((f.backFace()[1]-f.frontFace()[0])*(0.5f)) + f.frontFace()[0];
					glTranslatef(p3.x1,p3.x2,p3.x3);
					glBegin(GL_LINES);
						glVertex3f(0,0,0);
						glVertex3f(f.normals()[4].x1,f.normals()[4].x2,f.normals()[4].x3);
					glEnd();
				glPopMatrix();

				// nearPlane
				glColor3f(1.0f,1.0f,0.0f);
				glPushMatrix();
					Point p4 = ((f.frontFace()[1]-f.frontFace()[3])*(0.5f)) + f.frontFace()[3];
					glTranslatef(p4.x1,p4.x2,p4.x3);
					glBegin(GL_LINES);
						glVertex3f(0,0,0);
						glVertex3f(f.normals()[1].x1,f.normals()[1].x2,f.normals()[1].x3);
					glEnd();
				glPopMatrix();

				// rightPlane
				glColor3f(0.0f,1.0f,1.0f);
				glPushMatrix();
					Point p5 = ((f.backFace()[0]-f.frontFace()[3])*(0.5f)) + f.frontFace()[3];
					glTranslatef(p5.x1,p5.x2,p5.x3);
					glBegin(GL_LINES);
						glVertex3f(0,0,0);
						glVertex3f(f.normals()[3].x1,f.normals()[3].x2,f.normals()[3].x3);
					glEnd();
				glPopMatrix();

				// bottomPlane
				glColor3f(1.0f,0.0f,1.0f);
				glPushMatrix();
					Point p6 = ((f.backFace()[2]-f.frontFace()[3])*(0.5f)) + f.frontFace()[3];
					glTranslatef(p6.x1,p6.x2,p6.x3);
					glBegin(GL_LINES);
						glVertex3f(0,0,0);
						glVertex3f(f.normals()[5].x1,f.normals()[5].x2,f.normals()[5].x3);
					glEnd();
				glPopMatrix();
			}
		}

		static void drawCubeIntersect(Cube& c1,const Cube& c2,bool drawNormals=false){
			glDisable(GL_LIGHTING);
			glColor3f(1,1,1);
			if(c1.intersect(c2))
				glColor3f(1,0,0);
			drawCube(c1);
			drawCube(c2);
			glEnable(GL_LIGHTING);
		}

		static void drawFrustumCubeIntersect(const Frustum& f1,const Cube& c2,bool drawNormals=false){
			glDisable(GL_LIGHTING);
			glColor3f(1,1,1);
			drawFrusutm(f1,drawNormals);
			if(f1.intersect(c2))
				glColor3f(1,0,0);
			drawCube(c2);
			glEnable(GL_LIGHTING);
		}

		// TODO
	//	static void drawRectangle(const Rectangle& r){
	//		// TODO
	//	}
};

#endif /* GEOMETRY_DEBUG_HELPER_H_ */
